package com.stroke.core;

import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

import javax.swing.*;
import java.io.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * Author: Igor Bubelov
 * Date: 3/7/11 5:45 PM
 */
public class KeyMapParser {
    public static Map<KeyStroke, Action> parse(String path) {
        File file = new File(path);

        if (!file.exists()) {
            Logger.getRootLogger().error("Cannot find keyMap at path: " + file.getAbsolutePath());
            return null;
        }

        final Map<KeyStroke, Action> result = new HashMap<KeyStroke, Action>();

        XMLReader reader;

        try {
            reader = XMLReaderFactory.createXMLReader();
        } catch (SAXException ex) {
            Logger.getLogger(ConfigurationBuilder.class).error("Failed to create XML reader", ex);
            return null;
        }

        DefaultHandler handler = new DefaultHandler() {
            @Override
            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
                if (qName.equals("stroke")) {
                    Map<KeyStroke, Action> entry = createEntry(attributes);

                    if (entry != null) {
                        result.putAll(entry);
                    }
                }
            }
        };

        reader.setContentHandler(handler);

        try {
            reader.parse(new InputSource(new FileInputStream(file)));
        } catch (Exception ex) {
            Logger.getLogger(KeyMapParser.class).error("Failed to parse KeyMap configuration", ex);
        }


        return result;
    }

    private static Map<KeyStroke, Action> createEntry(Attributes attributes) {
        String exp = attributes.getValue("exp");

        if (exp == null) {
            Logger.getLogger(KeyMapParser.class).error("KeyStroke's expression doesn't set");
            return null;
        }

        KeyStroke keyStroke = KeyStroke.getKeyStroke(exp);

        if (keyStroke == null) {
            Logger.getLogger(KeyMapParser.class).error("Incorrect expression: " + exp);
            return null;
        }

        String classPath = attributes.getValue("action");

        if (classPath == null) {
            Logger.getLogger(KeyMapParser.class).error("KeyStroke's action doesn't set");
            return null;
        }

        try {
            Class actionClass = Class.forName(classPath);
            Action action = (Action) actionClass.newInstance();

            return Collections.singletonMap(keyStroke, action);
        } catch (Exception ex) {
            Logger.getLogger(KeyMapParser.class).error("Can't load action for expression:" + exp, ex);
            return null;
        }
    }
}